home *** CD-ROM | disk | FTP | other *** search
- unit Splitter;
-
- interface
-
- uses
- WinProcs, WinTypes, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- ExtCtrls;
-
- type
- TOrientation = (soHorizontal, soVertical);
-
- TSplitter = class(TCustomPanel)
- private
- FForm: TForm;
- FSplitControl, FSizeTarget, FTargetControl: TControl;
- FVertical: Boolean;
- FOrientation: TOrientation;
- FSplit: TPoint;
- function GetSizing: Boolean;
- procedure DrawSizingLine;
- protected
- procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
- procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
- procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
- procedure SetOrientation(Value: TOrientation);
- procedure SetParent(AParent: TWinControl); override;
- public
- constructor Create(AOwner: TComponent); override;
- procedure BeginSizing(ASplitControl, ATargetControl: TControl);
- procedure ChangeSizing(X, Y: Integer);
- procedure EndSizing;
- property Sizing: Boolean read GetSizing;
- published
- property Align;
- property Orientation: TOrientation read FOrientation write SetOrientation default soVertical;
- property TargetControl: TControl read FTargetControl write FTargetControl;
- end;
-
- procedure Register;
-
- implementation
-
- function CToC(C1, C2: TControl; P: TPoint): TPoint;
- begin
- Result := C1.ScreenToClient(C2.ClientToScreen(P));
- end;
-
- procedure TSplitter.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
- begin
- if (Button = mbLeft) and (Shift = [ssLeft]) and (TargetControl <> nil) then
- BeginSizing(Self, TargetControl);
- end;
-
- procedure TSplitter.MouseMove(Shift: TShiftState; X, Y: Integer);
- begin
- if Sizing then ChangeSizing(X, Y);
- end;
-
- procedure TSplitter.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
- begin
- if Sizing then EndSizing;
- end;
-
- procedure TSplitter.SetOrientation(Value: TOrientation);
- begin
- if FOrientation <> Value then
- begin
- FOrientation := Value;
- BevelOuter := bvNone;
- Caption := '';
- case Value of
- soHorizontal:
- begin
- Align := alTop;
- Cursor := crVSplit;
- Height := 2;
- end;
- soVertical:
- begin
- Align := alLeft;
- Cursor := crHSplit;
- Width := 2;
- end;
- end;
- end;
- end;
-
- procedure TSplitter.SetParent(AParent: TWinControl);
- begin
- inherited SetParent(AParent);
- end;
-
- constructor TSplitter.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FForm := AOwner as TForm;
- Orientation := soVertical;
- end;
-
- function TSplitter.GetSizing: Boolean;
- begin
- Result := Assigned(FSplitControl);
- end;
-
- procedure TSplitter.DrawSizingLine;
- var
- P: TPoint;
- begin
- P := CToC(FForm, FSplitControl, FSplit);
- with FForm.Canvas do
- begin
- MoveTo(P.X, P.Y);
- if FVertical then
- LineTo(CToC(FForm, FSplitControl, Point(FSplitControl.Width, 0)).X, P.Y)
- else
- LineTo(P.X, CToC(FForm, FSplitControl, Point(0, FSplitControl.Height)).Y)
- end;
- end;
-
- procedure TSplitter.BeginSizing(ASplitControl, ATargetControl: TControl);
- begin
- FSplitControl := ASplitControl;
- FSizeTarget := ATargetControl;
- SetCaptureControl(FSplitControl);
- FVertical := ASplitControl.Width > ASplitControl.Height;
- if FVertical then
- FSplit := Point(0, ASplitControl.Top)
- else
- FSplit := Point(ASplitControl.Left, 0);
- FForm.Canvas.Handle := GetDCEx(FForm.Handle, 0,
- DCX_CACHE or DCX_CLIPSIBLINGS or DCX_LOCKWINDOWUPDATE);
- with FForm.Canvas do
- begin
- Pen.Color := clWhite;
- if FVertical then
- Pen.Width := ASplitControl.Height
- else
- Pen.Width := ASplitControl.Width;
- Pen.Mode := pmXOR;
- end;
- DrawSizingLine;
- end;
-
- procedure TSplitter.ChangeSizing(X, Y: Integer);
- begin
- DrawSizingLine;
- if FVertical then
- FSplit.Y := Y
- else
- FSplit.X := X;
- DrawSizingLine;
- end;
-
- procedure TSplitter.EndSizing;
- var
- DC: HDC;
- P: TPoint;
- begin
- DrawSizingLine;
- P := CToC(FSizeTarget, FSplitControl, FSplit);
- SetCaptureControl(nil);
- FSplitControl := nil;
- with FForm do
- begin
- DC := Canvas.Handle;
- Canvas.Handle := 0;
- ReleaseDC(Handle, DC);
- end;
- if FVertical then
- FSizeTarget.Height := P.Y
- else
- FSizeTarget.Width := P.X;
- end;
-
- procedure Register;
- begin
- RegisterComponents('Samples', [TSplitter]);
- end;
-
- end.
-